home *** CD-ROM | disk | FTP | other *** search
- ;* SCHEME.ASM
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Borland TASM code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Many init-time scheme objects (no code) *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 26 Feb 86: Modified the initial value of the global variable *
- ;* "listpage" so that it points to page zero (0) instead of *
- ;* END_LIST. This causes it to always point to a valid page, *
- ;* thus eliminating one check for each CONS operation. (JCJ) *
- ;* - 22 May 86: changed debug flag in R2 used as VM starts up; *
- ;* if none, R2=0 (nil), else R2=tagged fixnum zero (rb) *
- ;* - 10 Feb 87: Changed page 5 special symbols to for #T instead of *
- ;* #!TRUE for the R^3 Report. (tc) *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- IDEAL
- %PAGESIZE 60, 132
- MODEL medium
- LOCALS @@
-
- INCLUDE "scheme.ash"
- INCLUDE "assembly.ash"
-
- DATASEG
-
- ; Page Table - This area of memory holds the table of base
- ; (paragraph) addresses for each of the page
- ; frames in Scheme's memory system.
- MONKEY = $
- pagetable DW NUMPAGES dup (?)
- ORG MONKEY
- DW NILPAGE ; page 0 - 'nil or cdr nil
- DW 0 ; page 1 - characters (immediates)
- DW 0 ; page 2 - forwarded pointer
- DW 0 ; page 3 - 15-bit fixnums (immediates)
- DW FLTPAGE ; page 4 - special 32-bit flonums
- DW SMBPAGE ; page 5 - special symbols
- DW PRTPAGE ; page 6 - standard port page
- DW CODPAGE ; page 7 - code for test programs
- DW NVTPAGE ; page 8 - initial environments
- ; remainder of page table
- DW NUMPAGES-PREALLOC dup (0)
-
- ; Page Attribute Table - The bits in the following table are
- ; used to indicate the state of each of the pages
- ; in the Scheme memory system. Only one kind of data
- ; object can be stored in a given page, so a single bit
- ; can be used to classify all references to a page.
-
- MONKEY = $
- attrib DW NUMPAGES dup (?)
- ORG MONKEY
- DW ATOM+READONLY
- DW ATOM+CHARS+READONLY+NOMEMORY
- DW NOMEMORY
- DW ATOM+FIXNUMS+READONLY+NOMEMORY
- DW ATOM+FLONUMS+READONLY
- DW ATOM+SYMBOLS+READONLY
- DW ATOM+PORTS+READONLY
- DW ATOM+CODE
- DW ATOM ; Initial Environments
- DW NUMPAGES-PREALLOC dup (NOMEMORY)
-
- ; Next available location table - The following table contains
- ; the offsets of the next available location which
- ; may be allocated in each page. A negative value
- ; indicates that the page is full and that no further
- ; allocation is possible within a page.
-
- MONKEY = $
- nextcell DW NUMPAGES dup (?)
- ORG MONKEY
- DW DEDPAGES dup (END_LIST)
- DW NVTPAGE:env_nxt ; Environments page
- DW NUMPAGES-PREALLOC dup (END_LIST)
-
- ; Page link table - Pages which contain data objects of the same
- ; type are linked together via the following table.
-
- pagelink DW NUMPAGES dup (END_LIST)
-
- ; Page type table - This table holds the "type" of each page for
- ; pointer classification purposes. The values in
- ; this table may be used as indicies into branch
- ; tables.
-
- MONKEY = $
- ptype DB NUMPAGES dup (?)
- ORG MONKEY
- DW LISTTYPE ; Page 0 contains list cells
- DW CHARTYPE ; Page 1 is for character immediates
- DW FREETYPE ; Page 2 is for "forwarded pointers"
- DW FIXTYPE ; Page 3 is for fixnum immediates
- DW FLOTYPE ; Page 4 contains pre-defined flonums
- DW SYMBTYPE ; Page 5 contains pre-defined symbols
- DW PORTTYPE ; Page 6 contains standard I/O ports
- DW CODETYPE ; Page 7 contains test programs
- DW ENVTYPE ; Page 8 contains environments
- DW NUMPAGES-PREALLOC dup (FREETYPE) ; Rest of pages not pre-allocated
-
- MONKEY = $
- psize DW NUMPAGES dup (?)
- ORG MONKEY
- DW NILPAGESIZE ; Page 0 contains special list cells
- DW 0 ; Page 1 is a tag for immediate characters
- DW 0 ; Page 2 reserved for "forwarded pointers"
- DW 0 ; Page 3 is a tag used for immediate fixnums
- DW FLTPAGESIZE ; Page 4 contains pre-defined flonums
- DW SMBPAGESIZE ; Page 5 contains pre-defined symbols
- DW PRTPAGESIZE ; Page 6 contains standard I/O ports
- DW CODPAGESIZE ; Page 7 contains test programs
- DW NVTPAGESIZE ; Page 8 contains environments
- DW NUMPAGES-PREALLOC dup (MIN_PAGESIZE) ; Initialize default page size
-
- ; Table of pages for allocation by type
-
- MONKEY = $
- pagelist DW NUMTYPES dup (?)
- ORG MONKEY
- listpage DW 0 ; [0] Page number for list cell allocation
- fixpage DW END_LIST ; [1] Page number for fixnum allocation
- flopage DW END_LIST ; [2] Page number for flonum allocation
- bigpage DW END_LIST ; [3] Page number for bignum allocation
- sympage DW END_LIST ; [4] Page number for symbol allocation
- stpage DW END_LIST ; [5] Page number for string allocation
- vectpage DW END_LIST ; [6] Page number for vector allocation
- contpage DW END_LIST ; [7] Page number for continuation allocation
- clospage DW END_LIST ; [8] Page number for closure allocation
- freepage DW END_LIST ; [9] Free page list header
- codepage DW END_LIST ; [10] Page number for code block allocation
- i86page DW END_LIST ; [11] Page number for inline code allocation
- portpage DW END_LIST ; [12] Page number for port allocation
- chapage DW END_LIST ; [13] Page number for characters
- envpage DW ENV_PAGE ; [14] Page for environments
-
- ; Table of page attributes by data object type
- MONKEY = $
- pageattr DW NUMTYPES dup (?)
- ORG MONKEY
- DW LISTCELL ; [0] List cell attributes
- DW ATOM+FIXNUMS ; [1] Fixnum attributes
- DW ATOM+FLONUMS ; [2] Flonum attributes
- DW ATOM+BIGNUMS ; [3] Bignum attributes
- DW ATOM+SYMBOLS ; [4] Symbol attributes
- DW ATOM+STRINGS ; [5] String attributes
- DW ATOM+VECTORS ; [6] Vector (array) attributes
- DW ATOM+CONTINU ; [7] Continuation attributes
- DW ATOM+CLOSURE ; [8] Closure attributes
- DW 0 ; [9] Free page has no attributes
- DW ATOM+CODE ; [10] Code block attributes
- DW ATOM+I86CODE ; [11] Inline 8086 code attributes
- DW ATOM+PORTS ; [12] Port attributes
- DW ATOM+CHARS ; [13] Character attributes
- DW ATOM ; [14] Environment attributes
-
- nextpage DW PREALLOC ; Next unused page number
- lastpage DW PREALLOC ; Will hold last page #
- nextpara DW 0 ; Next available paragraph number
- PAGESIZE DW MIN_PAGESIZE
-
- ; "Registers" for the Scheme Virtual Machine
-
- MONKEY = $
- regs REG NUM_REGS dup (?)
- ORG MONKEY
- reg0 REG < NIL_DISP, NIL_PAGE*2 >; Virtual register 0 - always nil
- LABEL reg1 REG
- REG NUM_REGS-1 dup (< UN_DISP, UN_PAGE*2 >)
-
- tmp_adr DW tmp_reg ; addresses of temporary registers
- tm2_adr DW tm2_reg
-
- s_pc DW CODPAGE:entry
-
- ; Storage for oblist hash table
- hash_page DB HT_SIZE dup (0)
- hash_disp DW HT_SIZE dup (0)
-
- ; Storage for property list hash table
- prop_page DB HT_SIZE dup (0)
- prop_disp DW HT_SIZE dup (0)
-
- obj_hlist POINTER <0, 0> ; object hashing
-
- ; Stack storage (stack buffer)
- LABEL s_stack STKFDEF
- POINTER < NIL_PAGE*2, NIL_DISP >; caller's code base pointer
- POINTER < SPECFIX*2, 0 > ; return address displacement
- POINTER < SPECFIX*2, 0 > ; caller's frame pointer
- POINTER < ENV_PAGE*2, NVTPAGE:g_env >; current heap environment
- POINTER < SPECFIX*2, 0 > ; static link
- POINTER < NIL_PAGE*2, NIL_DISP >; closure pointer ('nil means open call)
- STK_HEAD = $-s_stack
- DB STKSIZE-STK_HEAD dup (0)
-
- topofstack DW STK_HEAD-SIZE POINTER ; current top-of-stack pointer
- frameptr DW 0 ; current stack frame pointer
- base DW 0 ; stack buffer base
-
- ; State variables for (reset) and (scheme-reset)
- fp_save DW 0 ; save area for nominal stack
- rst_ent DW reset_x ; entry point for reset code
- err_ent DW err_rtn ; entry point for error handler invocation
-
- ; Flags for VM Control
- vm_debug DW 0 ; flag indicating VM_debug mode
- s_break DB 0 ; flag indicating shift-break key depressed
-
- ; Special storage for nil
- SEGMENT NILPAGE PARA PUBLIC 'FAR_DATA'
- POINTER < NIL_PAGE*2, NIL_DISP >; Special constant: (cons nil nil)
- POINTER < NIL_PAGE*2, NIL_DISP >
- NILPAGESIZE = $ ; end of Page 0
- ENDS NILPAGE
-
- ; Special 64-bit floating point constants area
- SEGMENT FLTPAGE PARA PUBLIC 'FAR_DATA'
- P8087
- FLODEF { data = -1.0 }
- FLODEF { data = 0.0 }
- FLODEF { data = 1.0 }
- FLTPAGESIZE = $ ; end of Page 4
- ENDS FLTPAGE
-
- ; Define symbol constant
- MACRO symbol str
- local first, last
- first DB SYMBTYPE ; tag
- DW last-first ; length field
- POINTER < NIL_PAGE*2, NIL_DISP >; link field page number - initially null
- DB 0 ; hash key - 0 for "special symbols"
- DB str ; character data
- last = $
- ENDM
-
- ; Special storage for single character symbols
- SEGMENT SMBPAGE PARA PUBLIC 'FAR_DATA'
- LABEL t_symbol unknown
- symbol "#T" ; #T for #!true for 't for true
- symbol "#!UNASSIGNED" ; the proverbial undefined value
- symbol "#!NOT-A-NUMBER" ; undefined result of arithmetic
- LABEL eof_sym unknown
- symbol "#!EOF" ; end-of-file indicator
- LABEL non_prt unknown
- symbol "#!UNPRINTABLE" ; value of *the-non-printing-object*
- SMBPAGESIZE = $ ; end of Page 5
- ENDS SMBPAGE
-
- SEGMENT PRTPAGE PARA PUBLIC 'FAR_DATA'
- ; Standard Input Port
- stdinp DB PORTTYPE ; tag=PORT
- DW stdinp_-stdinp ; length of object in BYTEs
- POINTER < NIL_PAGE*2, NIL_DISP >; null pointer
- DW 01001111b ; flags (binary, window, read & write)
- DW 0 ; handle (stdin CON)
- DW 0 ; cursor line
- DW 0 ; cursor column
- DW 0 ; upper left line
- DW 0 ; upper left column
- DW 0 ; number of lines
- DW 0 ; number of columns
- DW -1 ; border attributes (none)
- DW 000FH ; text attributes (white, enable)
- DW 00000011b ; window flags (transcript, wrap)
- DW 0 ; current buffer position
- DW 0 ; current end of buffer
- DB BUFFSIZE dup (0) ; input buffer
- POINTER < NIL_PAGE*2, NIL_DISP >; no pointer to next window
- stdinp_ = $
-
- ; The following point object is now used for the pcs-status-window
- stdoutp DB PORTTYPE ; tag=PORT
- DW stdoutp_-stdoutp ; length of object in BYTEs
- POINTER < NIL_PAGE*2, NIL_DISP >; null pointer
- DW 01001111b ; flags (binary, window, read & write)
- DW 1 ; handle (stdout CON)
- DW 0 ; cursor line
- DW 0 ; cursor column
- DW 0 ; upper left line
- DW 0 ; upper left column
- DW 1 ; number of lines
- DW 0 ; number of columns
- DW -1 ; border attributes (none)
- DW 001CH ; text attrs (reverse video, green, enable)
- DW 00000001b ; window flags (no transcript, wrap)
- DW 0 ; current buffer position
- DW 0 ; current end of buffer
- DB BUFFSIZE dup (0) ; output buffer
- POINTER < SPECPOR*2, 0 > ; pointer to previously defined window
- stdoutp_ = $
- PRTPAGESIZE = $ ; end of Page 6
- ENDS PRTPAGE
-
- ; Environments
- SEGMENT NVTPAGE PARA PUBLIC 'FAR_DATA'
- ENV_PAGE = 8
- ; define USER-GLOBAL-ENVIRONMENT
- LABEL g_env ENVDEF
- DB ENVTYPE
- DW g_env_-g_env
- POINTER < NIL_PAGE*2, NIL_DISP >; parent pointer (there is no parent)
- POINTER HT_SIZE dup (< NIL_PAGE*2, NIL_DISP >)
- g_env_ = $
-
- ; define USER-INITIAL-ENVIRONMENT
- LABEL u_env ENVDEF
- DB ENVTYPE
- DW u_env_-u_env
- POINTER < ENV_PAGE*2, g_env >
- POINTER HT_SIZE dup (< NIL_PAGE*2, NIL_DISP >)
- u_env_ = $
-
- ;define PCS-RESERVED-SYMBOLS-ENVIRONMENT (factice environment, link to prop list)
- LABEL r_env ENVDEF
- DB ENVTYPE
- DW r_env_-r_env
- POINTER < ENV_PAGE*2, g_env >
- POINTER 2 dup (< NIL_PAGE*2, NIL_DISP >)
- r_env_ = $
-
- LABEL env_nxt ENVDEF
- NVTPAGESIZE = env_nxt+(1*SIZE ENVDEF) ; allow room for 1 environment
- DB FREETYPE
- DW NVTPAGESIZE-env_nxt
- DB NVTPAGESIZE-$ dup (0)
- ENDS NVTPAGE
-
- ; Assembly area for test programs
- SEGMENT CODPAGE PARA PUBLIC 'FAR_DATA'
- DB CODETYPE ; Block header
- DW CODPAGESIZE
- FIXNUM <, entry > ; Code starting offset
- ; Constant (pointers) go here
- s_top_level = 0
- POINTER < NIL_PAGE*2, NIL_DISP >; "scheme-top-level" symbol goes here
- CREAD = 1
- POINTER < NIL_PAGE*2, NIL_DISP >; "read" symbol goes here
- CEOF = 2
- POINTER < NIL_PAGE*2, NIL_DISP >; interned "eof" symbol goes here
- CINP = 3
- POINTER < NIL_PAGE*2, NIL_DISP >; interned "input-port" symbol goes here
- COUTP = 4
- POINTER < NIL_PAGE*2, NIL_DISP >; interned "output-port" symbol goes here
- CCONS = 5
- POINTER < NIL_PAGE*2, NIL_DISP >; interned "console" symbol goes here
- CNO_PRT = 6
- POINTER < NIL_PAGE*2, NIL_DISP >; interned "*the-non-printing-object*" sym
- CUGENV = 7
- POINTER < NIL_PAGE*2, NIL_DISP >; interned "user-global-environment" sym
- CUIENV = 8
- POINTER < NIL_PAGE*2, NIL_DISP >; interned "user-initial-environment" sym
- CRSENV = 9
- POINTER < NIL_PAGE*2, NIL_DISP >; interned "pcs-reserved-symbols-environment" sym
- err_name = 10
- POINTER < NIL_PAGE*2, NIL_DISP >; interned "*error-handler*" symbol
- CWHO = 11
- POINTER < NIL_PAGE*2, NIL_DISP >; interned "pcs-status-window"
- kill_engine = 12
- POINTER < NIL_PAGE*2, NIL_DISP >; interned "PCS-KILL-ENGINE"
- CEOFX = 13
- POINTER < SPECSYM*2, SMBPAGE:eof_sym >; special non-interned "eof" symbol
- CNO_PRTX = 14
- POINTER < SPECSYM*2, SMBPAGE:non_prt >; special non-interned "#!unprintable" sym
- CUGENVX = 15
- POINTER < ENV_PAGE*2, NVTPAGE:g_env >; pointer to user-global-environment
- CUIENVX = 16
- POINTER < ENV_PAGE*2, NVTPAGE:u_env >; pointer to user-initial-environment
- CRSENVX = 17
- POINTER < ENV_PAGE*2, NVTPAGE:r_env >; pointer to pcs-reserved-symbols-environment
- CWHOX = 18
- POINTER < SPECPOR*2, PRTPAGE:stdoutp >; pointer to "who-line" window object
- LABEL entry
- VM_NUM? R2 ; second input argument 0 specified?
- VM_JNLs R2, no_debug ; if not, don't begin debug (jump)
- VM_DBG ; initiate debug mode
- LABEL no_debug
-
- VM_MVC R63, CEOFX ; define "eof"
- VM_DEF R63, CEOF
- VM_MVC R63, CNO_PRTX ; define "*the-non-printing-object*" to "#!unprintable"
- VM_DEF R63, CNO_PRT
- VM_MVC R63, CUGENVX ; define "user-global-environment" to point to said
- VM_DEF R63, CUGENV
- VM_MVC R63, CUIENVX ; define "user-initial-environment" to point to said
- VM_DEF R63, CUIENV
- VM_MVC R63, CRSENVX ; define "pcs-reserved-symbols-environment" to point to said
- VM_DEF R63, CRSENV
- VM_MVC R63, CWHOX ; define "who-line"
- VM_DEF R63, CWHO
- VM_MVC R63, CCONS ; fluid-bind "input-port", "output-port" to 'console
- VM_BIND CINP, R63
- VM_BIND COUTP, R63
- VM_BIND s_top_level, R0 ; fluid-bind "scheme-top-level" to nil
- VM_MVC R63, err_name ; establish the default error handler
- VM_CLO R63, err_default, 0
- VM_DEF R63, err_name
- VM_MVC R63, kill_engine ; establish the default PCS-KILL-ENGINE
- VM_CLO R63, ret_default, 0
- VM_DEF R63, kill_engine
- ; check the input parameter to see if it's a filename
- VM_FASL R1 ; fast load first program unit
- LABEL next_rd
- VM_MOV R8, R0
- VM_FASL R8
- VM_MVC R9, CEOFX
- VM_JEQs R9, R8, end_rd
- VM_PUSH R8 ; save program just read
- VM_EXEC R1 ; execute the previously read program
- VM_POP R1 ; restore pointer to most recently read pgm
- VM_JMPs next_rd ; see if more procedures follow
- LABEL end_rd
- VM_EXEC R1 ; Load program-Create the closure
- VM_MOV R2, R1 ; Copy returned value to R2
- VM_SYM? R2 ; Was a symbol returned?
- VM_JNLs R2, not_sym ; If not, don't try to look it up
- VM_MOV R2, R1
- VM_FLU? R2
- VM_JNLs R2, glob_sym
- VM_MVF R1, R1
- VM_JMPs not_sym
- LABEL glob_sym
- VM_MVG R1, R1 ; Look up symbol in global environment
- LABEL not_sym
- VM_MOV R2, R1
- VM_CLO? R2
- VM_JNLs R2, not_clos
- VM_CLCL R1, 0
- LABEL not_clos
- VM_NIL R2
- VM_PRT R1, R2 ; Print the result (if any)
- LABEL hardexit
- VM_MVI R1, 0ffh ; Error code
- VM_HALT R1
-
- ; Reset Code
- VM_SRST ; debugger entry for forced reset
- LABEL reset_x
- VM_MVG R1, kill_engine
- VM_CLCL R1, 0
- VM_CLEARREGS
- VM_MVF R1, s_top_level
- VM_JNLs R1, hardexit
- VM_CLCL R1, 0
- VM_JMPs reset_x ; if control returns, reset again
-
- ; Error Handler Invocation
- LABEL err_rtn
- reg_ctr = R1
- REPT NUM_REGS-1
- VM_PUSH reg_ctr
- reg_ctr = reg_ctr+4
- ENDM
- VM_MVG R1, err_name
- VM_CLCL R1, 0
- reg_ctr = (NUM_REGS-1)*4
- REPT NUM_REGS-1
- VM_POP reg_ctr
- reg_ctr = reg_ctr-4
- ENDM
- VM_EXIT
- LABEL err_default
- VM_DBG
- LABEL ret_default
- VM_EXIT
- CODPAGESIZE = $
- ENDS CODPAGE
-
- END
-